// 内存管理常见面试题

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void GetMemory(char* p)
{
	p = (char*)malloc(100);
}
void Test(void)
{
	char* str = NULL;
	GetMemory(str);
	strcpy(str, "hello world");
	printf(str);
}
int main()
{
	Test();
	return 0;
}

// 分析
// str作为实参,p为str的形参,形参的改变并不会影响实参
// str依旧为NULL
// strcpy函数中解引用NULL导致错误 && p变量malloc出来的内存并没有释放

// 正确代码
#include <assert.h>
#include <stdlib.h>
#include <string.h>
void GetMemory(char** p)
{
	assert(p);
	*p = (char*)malloc(100);
}
void Test(void)
{
	char* str = NULL;
	GetMemory(&str);
	strcpy(str, "hello world");
	printf(str);
	free(str);
	str = NULL;
}
int main()
{
	Test();
	return 0;
}

// -----------------------------------------------------------------------------

#include <stdio.h>
char* GetMemory(void)
{
	char p[] = "hello world";
	return p;
}
void Test(void)
{
	char* str = NULL;
	str = GetMemory();
	printf(str);
}
int main()
{
	Test();
	return 0;
}

// p是数组,数组是栈空间,函数销毁会自动销毁,str依旧是NULL

// -----------------------------------------------------------------------------

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void GetMemory(char** p, int num)
{
	*p = (char*)malloc(num);
}
void Test(void)
{
	char* str = NULL;
	GetMemory(&str, 100);
	strcpy(str, "hello");
	printf(str);
}
int main()
{
	Test();
	return 0;
}

// 分析
// 并没有释放malloc内存并且没有对str断言

// 正确代码
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
void GetMemory(char** p, int num)
{
	*p = (char*)malloc(num);
}
void Test(void)
{
	char* str = NULL;
	GetMemory(&str, 100);
	assert(str);
	strcpy(str, "hello");
	printf(str);
	free(str);
	str = NULL;
}
int main()
{
	Test();
	return 0;
}

// -----------------------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
void Test(void)
{
	char* str = (char*)malloc(100);
	strcpy(str, "hello");
	free(str);
	if (str != NULL)
	{
		strcpy(str, "world");
		printf(str);
	}
}
int main()
{
	Test();
	return 0;
}

// 分析
// 并没有对str断言,strcpy中对str解引用可能会造成NULL指针解引用并且后面if语句没有意义
